home *** CD-ROM | disk | FTP | other *** search
- /* menu.c - menu interface functions
- *
- * WMlib - WindowMaker application programming interface
- *
- * Copyright (C) 1997 Alfredo K. Kojima
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
-
- #include "WMaker.h"
- #include "app.h"
- #include "menu.h"
-
-
- WMMenu*
- WMMenuCreate(WMAppContext *app, char *title)
- {
- wmMenu *menu;
-
- if (strlen(title)>255)
- return NULL;
-
- menu = malloc(sizeof(wmMenu));
- if (!menu)
- return NULL;
-
- menu->appcontext = app;
- menu->parent = NULL;
- menu->title = title;
- menu->entries = NULL;
- menu->first = NULL;
-
- menu->realized = False;
- menu->code = app->last_menu_tag++;
-
- menu->entryline = malloc(strlen(title)+32);
- menu->entryline2 = malloc(32);
- if (!menu->entryline || !menu->entryline2) {
- if (menu->entryline)
- free(menu->entryline);
- free(menu);
- return NULL;
- }
- sprintf(menu->entryline, "%i %i %s", wmBeginMenu, menu->code, title);
- sprintf(menu->entryline2, "%i %i", wmEndMenu, menu->code);
- return menu;
- }
-
-
- int
- WMMenuAddItem(WMMenu *menu, char *text, WMMenuAction action,
- void *clientData, WMFreeFunction freedata, char *rtext)
- {
- wmMenuEntry *entry;
-
- /* max size of right side text */
- if (rtext && strlen(rtext)>4)
- return -1;
-
- /* max size of menu text */
- if (strlen(text)>255)
- return -1;
-
- entry = malloc(sizeof(wmMenuEntry));
- if (!entry)
- return -1;
-
- entry->entryline = malloc(strlen(text)+100);
- if (!entry->entryline) {
- free(menu);
- return -1;
- }
-
- if (menu->entries)
- entry->order = menu->entries->order + 1;
- else {
- entry->order = 0;
- menu->first = entry;
- }
- entry->next = NULL;
- entry->prev = menu->entries;
- if (menu->entries)
- menu->entries->next = entry;
- menu->entries = entry;
-
- entry->menu = menu;
- entry->text = text;
- entry->shortcut = rtext;
- entry->callback = action;
- entry->clientData = clientData;
- entry->free = freedata;
- entry->tag = menu->appcontext->last_menu_tag++;
- entry->cascade = NULL;
- entry->enabled = True;
-
-
- if (!rtext)
- sprintf(entry->entryline, "%i %i %i %i %s", wmNormalItem,
- menu->code, entry->tag, True, text);
- else
- sprintf(entry->entryline, "%i %i %i %i %s %s", wmDoubleItem,
- menu->code, entry->tag, True, rtext, text);
- return entry->tag;
- }
-
-
-
- int
- WMMenuAddSubmenu(WMMenu *menu, char *text, WMMenu *submenu)
- {
- wmMenuEntry *entry;
-
- /* max size of menu text */
- if (strlen(text)>255)
- return -1;
-
- entry = malloc(sizeof(wmMenuEntry));
- if (!entry)
- return -1;
-
- entry->entryline = malloc(strlen(text)+100);
- if (!entry->entryline) {
- free(menu);
- return -1;
- }
-
- if (menu->entries)
- entry->order = menu->entries->order + 1;
- else {
- entry->order = 0;
- menu->first = entry;
- }
- entry->next = NULL;
- entry->prev = menu->entries;
- if (menu->entries)
- menu->entries->next = entry;
- menu->entries = entry;
- entry->menu = menu;
- entry->text = text;
- entry->shortcut = NULL;
- entry->callback = NULL;
- entry->clientData = NULL;
- entry->tag = menu->appcontext->last_menu_tag++;
- entry->cascade = submenu;
- entry->enabled = True;
-
- sprintf(entry->entryline, "%i %i %i %i %i %s", wmSubmenuItem,
- menu->code, entry->tag, True, submenu->code, text);
- return entry->tag;
- }
-
-
- static int
- countItems(WMMenu *menu)
- {
- wmMenuEntry *entry = menu->first;
- int c;
-
- c = 1;
- while (entry) {
- c++;
- if (entry->cascade) {
- c += countItems(entry->cascade);
- }
- entry = entry->next;
- }
- c++;
- return c;
- }
-
-
- static void
- addItems(char **slist, int *index, WMMenu *menu)
- {
- wmMenuEntry *entry = menu->first;
-
- slist[(*index)++] = menu->entryline;
- while (entry) {
- slist[(*index)++] = entry->entryline;
- if (entry->cascade) {
- addItems(slist, index, entry->cascade);
- }
- entry = entry->next;
- }
- slist[(*index)++] = menu->entryline2;
- }
-
-
- static Atom
- getatom(Display *dpy)
- {
- static Atom atom=0;
-
- if (atom==0) {
- atom = XInternAtom(dpy, WMMENU_PROPNAME, False);
- }
- return atom;
- }
-
- int
- WMRealizeMenus(WMAppContext *app)
- {
- int i, count;
- char **slist;
- XTextProperty text_prop;
-
- if (!app->main_menu)
- return False;
-
- /* first count how many menu items there are */
- count = countItems(app->main_menu);
- if (count==0)
- return True;
-
- count++;
- slist = malloc(count*sizeof(char*));
- if (!slist) {
- return False;
- }
-
- slist[0] = "WMMenu 0";
- i = 1;
- addItems(slist, &i, app->main_menu);
-
- if (!XStringListToTextProperty(slist, i, &text_prop)) {
- free(slist);
- return False;
- }
- free(slist);
- XSetTextProperty(app->dpy, app->main_window, &text_prop,
- getatom(app->dpy));
-
- XFree(text_prop.value);
-
- return True;
- }
-
-
-